package com.beta.cust.bind.datasync.api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.beta.cust.bind.datasync.config.CfgSelfRefreshBean;
import com.beta.cust.bind.datasync.dto.APPMsgReq;
import com.beta.cust.bind.datasync.utils.Xml2Json;
import com.beta.cust.bind.datasync.utils.wechat.AesException;
import com.beta.cust.bind.datasync.utils.wechat.WXBizMsgCrypt;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.common.utils.IOUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;


/**
 * 微信服务
 */
@Slf4j
public abstract class WxCallBackSupport {

    @Resource
    private CfgSelfRefreshBean cfgSelfRefreshBean;

    /**
     * 解密回调信息
     *
     * @param req
     * @return
     */
    protected String decryptCallbackInfo(APPMsgReq req) {
        String sToken = cfgSelfRefreshBean.getSToken();
        String sEncodingAESKey = cfgSelfRefreshBean.getSEncodingAESKey();
        String sCorpID = cfgSelfRefreshBean.getCorpId();

        //请求参数错误
        if (StringUtils.isBlank(sToken) || req.getMsg_signature() == null) {
            return "";
        }

        WXBizMsgCrypt wxcpt = null;
        String sEchoStr = "";

        try {
            wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);
            sEchoStr = wxcpt.VerifyURL(req.getMsg_signature(), req.getTimestamp(),
                    req.getNonce(), req.getEchostr());
            return sEchoStr;
        } catch (AesException e) {
            e.printStackTrace();
            log.error("请求解密失败，req[{}]", JSON.toJSONString(req), e);
        }
        return sEchoStr;
    }

    /**
     * 解析并且将请求报文转化为JSON
     *
     * @param request
     * @return
     */
    protected JSONObject decryptCallbackInfoJson(APPMsgReq req, HttpServletRequest request) {

        String sToken = cfgSelfRefreshBean.getSToken();
        String sEncodingAESKey = cfgSelfRefreshBean.getSEncodingAESKey();
        String sCorpID = cfgSelfRefreshBean.getCorpId();

        WXBizMsgCrypt wxcpt = null;
        try {

            wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);
            BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
            String sReqData = IOUtils.read(reader);
            String sMsg = wxcpt.DecryptMsg(req.getMsg_signature(), req.getTimestamp(), req.getNonce(), sReqData);

            if (StringUtils.isNotBlank(sMsg)) {
                return xmlToJSON(sMsg);
            }
        } catch (IOException | AesException e) {
            log.error("解析微信回调异常", e);
        }

        return null;
    }

    protected JSONObject xmlToJSON(String body) {
        Document doc = null;
        try {
            doc = DocumentHelper.parseText(body);
            JSONObject json = new JSONObject();
            Xml2Json.dom4j2Json(doc.getRootElement(), json);
            return json;

        } catch (DocumentException e) {
            e.printStackTrace();
            log.error("xmlToJSON 失败 body[{}]", body);
        }
        return null;
    }
}
